﻿using System;
using System.Diagnostics;
using System.ServiceProcess;
using System.Timers;
using System.IO;

namespace Xforge.MinecraftWrapperService
{
    public partial class Wrapper : ServiceBase
    {
        Process process;
        Timer timer;
        Timer consoleTimer;
        //StreamWriter logStream;

        public bool Started { get; set; }

        public Wrapper()
        {
            Debug.WriteLine("Wrapper constructor called");

            InitializeComponent();

            if (!System.Diagnostics.EventLog.SourceExists("MCWSvc"))
            {
                System.Diagnostics.EventLog.CreateEventSource("MCWSvc", "Application");
            }

            eventLog.Source = "MCWSvc";
            eventLog.Log = "Application";

            process = new Process();
            //logStream = new StreamWriter("console.log");

            timer = new Timer(5000);
            timer.Elapsed += new ElapsedEventHandler(CheckServer);

            consoleTimer = new Timer(1000);
            consoleTimer.Elapsed += new ElapsedEventHandler(consoleTimer_Elapsed);
        }

        void consoleTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            Debug.WriteLine(process.StandardOutput.ReadLine());
        }

        private void CheckServer(object sender, ElapsedEventArgs e)
        {
            Debug.WriteLine("CheckServer called");
#if DEBUG
            timer.Stop();
#endif
            process.Refresh();

            if (Started && !process.Responding)
            {
                Debug.WriteLine("Process not responding");

                process.Kill();
                Started = false;
                eventLog.WriteEntry("Minecraft Server was not responding and has been killed. It will now be restarted.");
            }

            if (!Started)
            {
                Debug.WriteLine("Process not running");

                process.StartInfo.FileName = Properties.Settings.Default.JavaCommand;
                process.StartInfo.Arguments = String.Format(
                    "-Xmx{0}M -jar {1} nogui",
                    Properties.Settings.Default.ServerMemory,
                    Properties.Settings.Default.ServerJar
                    );
                process.StartInfo.WorkingDirectory = Properties.Settings.Default.ServerPath;
                process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardInput = true;

                process.Start();
                Started = true;
                eventLog.WriteEntry("Minecraft Server has been started.");

                Debug.WriteLine("Process started");

                consoleTimer.Start();
            }

            //string consoleOutput = process.StandardOutput.ReadToEnd();
            //System.Console.Write(consoleOutput);
            //logStream.Write(consoleOutput);

#if DEBUG
            timer.Start();
#endif

            Debug.WriteLine("CheckServer done");
        }

        protected override void OnStart(string[] args)
        {
            Debug.WriteLine("OnStart called");
#if DEBUG
            eventLog.WriteEntry("Wrapper is running in Debug mode and will use an increased server start delay to make attaching the debugger possible.");
            timer.Interval = 25000;
#endif

            timer.Start();
        }

        protected override void OnStop()
        {
            Debug.WriteLine("OnStop called");

            timer.Stop();

            try
            {
                process.StandardInput.WriteLine("stop");
                Debug.WriteLine("Waiting for exit");
                process.WaitForExit(2000);

                if (!process.HasExited)
                {
                    Debug.WriteLine("Killing");
                    process.Kill();
                }
            }
            finally
            {
                process.Close();
                Started = false;
            }

            eventLog.WriteEntry("Minecraft Server has been stopped.");

            consoleTimer.Stop();

            Debug.WriteLine("OnStop done");
        }
    }
}
